﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Diagnostics;
using ERPStudio;
using System.Reflection;
using System.Data.SqlServerCe;
using System.IO;


namespace ERPForms
{
    public partial class UnitatiFrm : ERPStudio.FrmRezumat
    {
        
        private List<UnitatiSursa> lstUnitSursa = new List<UnitatiSursa>();
        private Int16 UnitateCurentaStart = 0;
        private Boolean BackupMode = false;

        public UnitatiFrm(ModuleClass mInfo, Boolean bkmode=false)
            : base(mInfo)
        {
            InitializeComponent();
            workConnString = mInfo.workConnectionString;
            this.HandleAfterAdd += new AfterAddHandler(UnitatiFrm_HandleAfterAdd);
            BackupMode = bkmode;
            ExportaColumn.Visible = BackupMode;
            UnitateCurentaColumn.ReadOnly = BackupMode;
            DenumireColumn.ReadOnly = BackupMode;
            if (BackupMode)
                Text = "Backup Unitati";
        }

        void UnitatiFrm_HandleAfterAdd(object sender, DataGridViewCellEventArgs args)
        {
            UnitateSursaColumn.Visible = true;
        }

        private void UnitatiFrm_Load(object sender, EventArgs e)
        {
            SetCurentUnit(0);
            
            AddBindingSource(unitatiBindingSource);
            this.listTableAdaptor.Add(this.unitatiTableAdapter.Adapter);
            if (!EsteArhiva())
            {
                if (!BackupMode)
                {
                    AddButton("Info[F11]", global::ERPStudio.Properties.Resources._001_07, Info, ToolStripItemAlignment.Right, true);
                    //AddButton("BackUp", global::ERPStudio.Properties.Resources._001_08, Backup, ToolStripItemAlignment.Right, true);
                    //AddButton("Restore", global::ERPStudio.Properties.Resources._001_09, Restore, ToolStripItemAlignment.Right, true);
                }
                HandleSalvare += new EventHandler(Salvare);
                HandleF11 += new EventHandler(Info);
            }
            else
            {
                MessageBox.Show("Schimbarea unitatii curente nu se poate face in momentul consultarii arhivei\nDaca totusi doriti acest lucru, reveniti in perioada curenta!",
                    "Atentie",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);

            }
            PopulateSourceUnit();

        }

        public void Info(object sender, EventArgs args)
        {
            if(unitatiBindingSource.Current==null)
                return;
            ESRPDataSet.UnitatiRow unir = ((DataRowView)unitatiBindingSource.Current).Row as ESRPDataSet.UnitatiRow;
            UnitatiInfoFrm frm = new UnitatiInfoFrm(ModuleInfo,unir.CodUnitate);
            //frm.MdiParent = this.MdiParent;
            frm.ShowDialog();

        }

        public void Restore(object sender, EventArgs args)
        {
            if (unitatiBindingSource.Current == null)
                return;
            ///creaza catalogul Backup
            ///
            string catCurent = Directory.GetCurrentDirectory();
            string catModule = catCurent + @"\Backup";
            DirectoryInfo catInfo = new DirectoryInfo(catModule);
            try
            {
                //creaza directorul unde se afla modulele
                //daca nu exista
                if (!Directory.Exists(catModule))
                {
                    catInfo = Directory.CreateDirectory(catModule);
                    MyTrace(DateTime.Now.ToString() + ":Directorul " + catInfo.FullName + " a fost creat cu succes");
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Nu este posibila crearea directorului Backup!. Cauza: " +
                    ex.Message);
                return;
            }

            RestoreUnitatiFrm frm = new RestoreUnitatiFrm(ModuleInfo);
            frm.ShowDialog();


        }

        public void Backup(object sender, EventArgs args)
        {
            if (unitatiBindingSource.Current == null)
                return;
            ///creaza catalogul Backup
            ///
            string catCurent = Directory.GetCurrentDirectory();
            string catModule = catCurent + @"\Backup";
            DirectoryInfo catInfo = new DirectoryInfo(catModule);
            try
            {
                //creaza directorul unde se afla modulele
                //daca nu exista
                if (!Directory.Exists(catModule))
                {
                    catInfo = Directory.CreateDirectory(catModule);
                    MyTrace(DateTime.Now.ToString() + ":Directorul " + catInfo.FullName + " a fost creat cu succes");
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Nu este posibila crearea directorului Backup!. Cauza: " +
                    ex.Message);
                return;
            }

            UnitatiFrm frm = new UnitatiFrm(ModuleInfo, true);
            frm.ShowDialog();


        }

        override public void Salvare(object sender, EventArgs args)
        {
            if (BackupMode)
            {
                /// transmite modificarile din grid in BindingSource
                unitatiDGV.EndEdit();
                ///verifica daca exista cel putin o unitate selectata
                ///pentru export
                Boolean celPutinUna = false;
                foreach(DataGridViewRow dr in unitatiDGV.Rows)
                {
                    if (Convert.ToBoolean(dr.Cells[ExportaColumn.Index].Value))
                    {
                        celPutinUna = true;
                        break;
                    }
                }
                if (!celPutinUna)
                {
                    MessageBoxFrm mbt = new MessageBoxFrm("Eroare backup", "Vă rugăm selectați cel puțin o unitate pentru export!", String.Empty, MessageBoxFrm.ImaginiMB.StopIcon, this);
                    mbt.AddButton("Ieşire", 70, mbt.MessageBoxFrm_Click_Yes);
                    mbt.ShowDialog();
                    return;
                }
                SqlConnection conn = DeschideConexiune(workConnString);
                DataTable dt = GetDatabaseColumsInformation(conn);
                InchideConexiune(conn);

                String databaseName = CreateBackup();
                if (!CreateStructure(databaseName,dt))
                    return;

                String unitatiSelectate = String.Empty;
                String denUnitatiSelectate = String.Empty;
                foreach (DataGridViewRow dr in unitatiDGV.Rows)
                {
                    if (Convert.ToBoolean(dr.Cells[ExportaColumn.Index].Value))
                    {
                        unitatiSelectate += dr.Cells[CodUnitateColumn.Index].Value.ToString() + ",";
                        denUnitatiSelectate += dr.Cells[DenumireColumn.Index].Value.ToString() + ",";
                    }
                }
                unitatiSelectate = unitatiSelectate.TrimEnd(new char[] { ',', '\n' });
                denUnitatiSelectate = denUnitatiSelectate.TrimEnd(new char[] { ',', '\n' });
                ExportaUnitate(unitatiSelectate, denUnitatiSelectate, databaseName);

                Close();
                return;
            }

            FrmMainMdi mdiF = MdiParent as FrmMainMdi;
            ///mai intai salvam modificarile
            SqlCommand cmd = new SqlCommand("", DeschideConexiune(workConnString));
            #region Apelare procedura stocate pentru stergerea unitatii
		    ///apelare procedura pentru stergerea unitatii
            ///
            DataRow[] deletedRows = eSRPDataSet.Unitati.Select(null, null, DataViewRowState.Deleted);
            if (((deletedRows != null) && (0 < deletedRows.Length)))
            {
                cmd.CommandText = "[StergeUnitate]";
                cmd.CommandType = CommandType.StoredProcedure;

                foreach(DataRow dr in deletedRows)
                {
                    cmd.Parameters.Clear();
                    cmd.Parameters.Add(new SqlParameter("@CodUnitate",dr["CodUnitate",DataRowVersion.Original]));
                    cmd.Parameters.Add(new SqlParameter("@faraStergereTabelaUnitati",false));
                    
                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch
                    {
                        this.unitatiTableAdapter.Connection = cmd.Connection;
                        this.unitatiTableAdapter.Fill(this.eSRPDataSet.Unitati);
                        InchideConexiune(cmd.Connection);
                        if(mdiF!=null)
                            UnitateCurentaStart = mdiF.GetUnitateImplicita(workConnString, unitatiDGV);
                        return;                    
                    }
                }
            }

	        #endregion
            base.Salvare(sender,args);
                

            if (EroareSalvare)
            {
                this.unitatiTableAdapter.Connection = cmd.Connection;
                this.unitatiTableAdapter.Fill(this.eSRPDataSet.Unitati);
                InchideConexiune(cmd.Connection);
                if (mdiF != null)
                    UnitateCurentaStart = mdiF.GetUnitateImplicita(workConnString, unitatiDGV);
                return;
            }

                /// si apoi mai facem si alceva...
                /// 


            Boolean unaBifata = false;
            foreach (DataGridViewRow dr in unitatiDGV.Rows)
            {
                if (Convert.ToBoolean(dr.Cells["UnitateCurentaColumn"].EditedFormattedValue) == true)
                {
                    if (Convert.ToInt16(dr.Cells[CodUnitateColumn.Index].EditedFormattedValue) != UnitateCurentaStart)
                        if (MessageBox.Show("Schimbarea unitatii curente se face si in machetele deschise.\nDatele aflate in prelucrare, nesalvate, se vor pierde.\nSunteti sigur(a) ca doriti acest lucru?",
                            "Atentie",
                            MessageBoxButtons.YesNo,
                            MessageBoxIcon.Warning) == DialogResult.No)
                        {
                            InchideConexiune(cmd.Connection);
                            return;
                        }

                    unaBifata = true;
                    //exista o singura unitate curenta
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = "UPDATE [SetariLocale] SET Valoare = " +
                        dr.Cells["CodUnitateColumn"].Value.ToString() + " WHERE [xUser] = system_user AND [xHost]=host_name() AND [CodSetare]='UCRT' AND [CodUnitate]=0";
                    int retObj = cmd.ExecuteNonQuery();
                    ModuleInfo.CodUnitate = Convert.ToInt16(dr.Cells["CodUnitateColumn"].Value.ToString());
                    //Trace.Assert(retObj == 1, "Numar randuri afectate eronat");
                    cmd.CommandText = "SELECT [Denumire] FROM [Unitati] WHERE [CodUnitate]=" + ModuleInfo.CodUnitate.ToString();
                    Object retObjUni = cmd.ExecuteScalar();

                    if (retObjUni != null && retObjUni != DBNull.Value)
                    {
                        NumeUnitate = retObjUni.ToString();
                        if (MdiParent != null)
                        {
                            ((ERPStudio.FrmMainMdi)MdiParent).SetUnitName(NumeUnitate);
                            foreach (eInfoModule asm1 in ((ERPStudio.FrmMainMdi)MdiParent).listaModule)
                            {
                                String NumeWS = asm1.module.ManifestModule.Name;
                                NumeWS = NumeWS.Replace(".dll", String.Empty);
                                String numeClasa1 = NumeWS + ".dscModule";
                                Type mModule1 = asm1.module.GetType(numeClasa1);

                            }
                        }
                    }

                    break;
                }

            }

            InchideConexiune(cmd.Connection);
            if (!unaBifata)
            {
                MessageBox.Show("Va rugam sa setati cel putin o unitate implicita.",
                            "Eroare",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
                return;
            }
            if(mdiF!=null)
                mdiF.ChangeCurrentUnit(ModuleInfo.CodUnitate, NumeUnitate);
            ///actualizare unitate la copi
            ///
            if (MdiParent != null)
            {
                foreach (Form frmChild in this.MdiParent.MdiChildren)
                {
                    if (frmChild != this)
                        ((StudioForm)frmChild).SetCurentUnit(ModuleInfo.CodUnitate);

                }
            }
            UnitateSursaColumn.Visible = false;
            Close();
        }

        private String CreateBackup()
        {
            string catCurent = Directory.GetCurrentDirectory();
            string catModule = catCurent + @"\Backup";
            /* get the Path */

            var fileName = System.IO.Path.Combine(catModule,"backup_"+ DateTime.Now.Year.ToString() + "_" +
                DateTime.Now.Month.ToString() + "_" + DateTime.Now.Day.ToString() + "_" + DateTime.Now.Hour.ToString()+"_"
                + DateTime.Now.Minute.ToString() + "_" + DateTime.Now.Second.ToString() + ".sdf");

            /* check if exists */
            if (File.Exists(fileName))
                File.Delete(fileName);

            string connStr = @"Data Source = " + fileName;

            /* create Database */
            SqlCeEngine engine = new SqlCeEngine(connStr);
            engine.CreateDatabase();
            return connStr;
        }


        private Boolean CreateStructure(String databaseName, DataTable datastructure)
        {
            SqlCeConnection conn = new SqlCeConnection(databaseName);
            String comanda = String.Empty;
            try
            {
                conn.Open();
                SqlTableCreator cre = new SqlTableCreator(conn);
                foreach (DataTable dt in exportESRPDataSet.Tables)
                {
                    cre.CreateFromDataTable(dt,datastructure,out comanda);
                    //cre.Create(dt, out comanda);
                }

                /// nu trebuie relatii in backup
                //foreach (DataRelation dr in exportESRPDataSet.Relations)
                //{
                //    cre.CreateFromDataRelation(dr, out comanda);
                //}

            }
            catch (Exception ex)
            {
                MessageBoxFrm mbt = new MessageBoxFrm("Eroare backup", comanda + ":" +ex.Message, String.Empty, MessageBoxFrm.ImaginiMB.StopIcon, this);
                mbt.AddButton("Ieşire", 70, mbt.MessageBoxFrm_Click_Yes);
                mbt.ShowDialog();
                return false;
            }
            finally
            {
                conn.Close();                
            }
            return true;

        }

        void ExportaUnitate(String MultimeCodUnitate, String denumire, String databaseName)
        {
            SqlCeConnection conn = new SqlCeConnection(databaseName);
            String comanda = String.Empty;

            SqlDataAdapter ta = new SqlDataAdapter(String.Empty,DeschideConexiune(workConnString));

            SqlTableCreator cre = null;
            try
            {
                conn.Open();
                cre = new SqlTableCreator(conn);
            }
            catch (Exception ex)
            {
                MessageBoxFrm mbt1 = new MessageBoxFrm("Eroare backup", comanda + ":" +ex.Message, String.Empty, MessageBoxFrm.ImaginiMB.StopIcon, this);
                mbt1.AddButton("Ieşire", 70, mbt1.MessageBoxFrm_Click_Yes);
                mbt1.ShowDialog();
                return;
            }

            DataView drc = null;
            
            ///incarca tabelele care au mai ramas
            foreach (DataTable dt in exportESRPDataSet.Tables)
            {
                if (exportESRPDataSet.Tables[dt.TableName].Rows.Count == 0)
                {
                    ta.SelectCommand.CommandText = "SELECT * FROM " + dt.TableName.ToString();
                    if (dt.Columns.Contains("CodUnitate"))
                        ta.SelectCommand.CommandText += " WHERE CodUnitate in (" + MultimeCodUnitate + ")";
                    ta.Fill(exportESRPDataSet.Tables[dt.TableName]);
                }
            }

            EnableProgressBar(0, exportESRPDataSet.Tables.Count);
            int poz = 0;
            foreach (DataTable dt in exportESRPDataSet.Tables)
            {
                SetProgressBar(poz++);
                if (exportESRPDataSet.Tables[dt.TableName].Rows.Count != 0)
                {
                    ta.SelectCommand.CommandText = "SELECT * FROM " + dt.TableName.ToString();

                    if (dt.Columns.Contains("CodUnitate"))
                        ta.SelectCommand.CommandText += " WHERE CodUnitate in (" + MultimeCodUnitate +")";
                    //if (dt.TableName.ToUpper() == "UNITATI")
                    //    ta.SelectCommand.CommandText += " OR CodUnitate=0";

                    ta.Fill(exportESRPDataSet.Tables[dt.TableName]);
                    cre.Transaction = cre.SourceConnection.BeginTransaction();
                    #region Conturi
                    if (dt.TableName.ToUpper() == "CONTURI")
                    {
                        ///insereaza contul radacina
                        exportESRPDataSet.Tables[dt.TableName].DefaultView.RowFilter = "CONT='N/A'";
                        DataView dna = exportESRPDataSet.Tables[dt.TableName].DefaultView;

                        try
                        {
                            cre.CreateFromDataRow(dt, dna[0], out comanda);
                        }
                        catch (Exception ex)
                        {
                            MessageBoxFrm mbt1 = new MessageBoxFrm("Eroare backup", comanda + ":" + ex.Message, String.Empty, MessageBoxFrm.ImaginiMB.StopIcon, this);
                            mbt1.AddButton("Ieşire", 70, mbt1.MessageBoxFrm_Click_Yes);
                            mbt1.ShowDialog();
                            cre.Transaction.Rollback();
                            return;
                        }

                        exportESRPDataSet.Tables[dt.TableName].DefaultView.RowFilter = "CONT<>'N/A'";
                        exportESRPDataSet.Tables[dt.TableName].DefaultView.Sort = "Terminal,Cont";
                    }
                    #endregion
                    drc = exportESRPDataSet.Tables[dt.TableName].DefaultView;

                    foreach (DataRowView dtr in drc)
                    {
                        try
                        {
                            cre.CreateFromDataRow(dt, dtr, out comanda);
                        }
                        catch (Exception ex)
                        {
                            MessageBoxFrm mbt1 = new MessageBoxFrm("Eroare backup", comanda + ":" + ex.Message, String.Empty, MessageBoxFrm.ImaginiMB.StopIcon, this);
                            mbt1.AddButton("Ieşire", 70, mbt1.MessageBoxFrm_Click_Yes);
                            mbt1.ShowDialog();
                            cre.Transaction.Rollback();
                            return;
                        }

                    }
                    cre.Transaction.Commit();

                }
            }
            DisableProgressBar();
            InchideConexiune(ta.SelectCommand.Connection);
            conn.Close();
            MessageBoxFrm mbt = new MessageBoxFrm("Informare", "Unitatile " + denumire + " a fost exportata cu succes!", String.Empty, MessageBoxFrm.ImaginiMB.InformareIcon, this);
            mbt.AddButton("Ok", 70, mbt.MessageBoxFrm_Click_Yes);
            mbt.ShowDialog();
        }
        

        private void PopulateSourceUnit()
        {
            foreach (DataGridViewRow dr in unitatiDGV.Rows)
            {
                ((DataGridViewComboBoxCell)dr.Cells["UnitateSursaColumn"]).ReadOnly = true;
            }
        
        }

        private void UnitatiFrm_Shown(object sender, EventArgs e)
        {
            UnitateCurentaStart = ModuleInfo.CodUnitate;
            foreach (DataGridViewRow dr in unitatiDGV.Rows)
            {
                if (Convert.ToInt16(dr.Cells["CodUnitateColumn"].Value) == UnitateCurentaStart)
                    dr.Cells["UnitateCurentaColumn"].Value = true;
            }
        }

        private void unitatiDGV_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            //daca nu sunt pe coloana cu unitate implicita
            if (unitatiDGV.Columns[e.ColumnIndex].Name != "UnitateCurentaColumn"||BackupMode)
                return;
            foreach (DataGridViewRow dr in unitatiDGV.Rows)
            {
                if (dr.Index == e.RowIndex)
                    continue;
                if (Convert.ToBoolean(dr.Cells["UnitateCurentaColumn"].Value) == true)
                    dr.Cells["UnitateCurentaColumn"].Value = false;
            }
        }

        private void unitatiDGV_Validating(object sender, CancelEventArgs e)
        {
            Int16 eUnul = 0;
            if (unitatiDGV.Rows.Count == 0)
            {
                e.Cancel = true;
                MessageBox.Show("Nu este posibila stergerea tuturor unitatilor functionale!", "Eroare", MessageBoxButtons.OK, MessageBoxIcon.Stop);            
            }
            foreach (DataGridViewRow dr in unitatiDGV.Rows)
            {
                if (Convert.ToBoolean(dr.Cells["UnitateCurentaColumn"].Value) == true)
                    eUnul++;
            }
            if (eUnul==0 || eUnul>1)
            { 
                // daca nu e nici una implicita e bai...
                e.Cancel = true;
                MessageBox.Show("Trebuie sa existe cel putin o untate implicita!", "Eroare", MessageBoxButtons.OK,MessageBoxIcon.Stop);
            }
            base.Validate();
        }
        
        override public void SetCurentUnit(short vCodUnitate)
        {
            this.unitatiTableAdapter.Connection = DeschideConexiune(workConnString);
            try
            {
                this.unitatiTableAdapter.Fill(this.eSRPDataSet.Unitati);
            }
            catch (Exception ex)
            {
                TrateazaExceptie(ex);
                return;
            }
            finally
            {
                InchideConexiune(unitatiTableAdapter.Connection);
            }
            FrmMainMdi mdiF = MdiParent as FrmMainMdi;
            eSRPDataSet.Unitati.UnitateSursaColumn.DefaultValue = ModuleInfo.CodUnitate;
            UnitatiFrm_Shown(this, null);
        }
        /// <summary>
        /// cand se apasa enter, controlul activ este luna, anul
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        override public void toolStripLabelAnLuna_Click(object sender, EventArgs e)
        {

        }

        override  public void Sterge(object sender, EventArgs e)
        {
            ConfirmareOperatieFrm frm = new ConfirmareOperatieFrm(ModuleInfo);
            if (frm.ShowDialog() == DialogResult.OK)
                base.Sterge(sender,e);

        }

    }
    [Serializable]
    public class UnitatiSursa
    {
        public UnitatiSursa(String nume, Int16 tag, String _type)
        {
            _Name = nume;
            _Tag = tag;
            _Type = _type;
        }

        private String _Name = String.Empty;
        [System.ComponentModel.Bindable(true)]
        public String Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name = value;
            }
        }
        private Int16 _Tag = 0;
        [System.ComponentModel.Bindable(true)]
        public Int16 Tag
        {
            get
            {
                return _Tag;
            }
            set
            {
                _Tag = value;
            }
        }
        private String _Type = "T";
        [System.ComponentModel.Bindable(true)]
        public String Type
        {
            get
            {
                return _Type;
            }
            set
            {
                _Type = value;
            }
        }

    }
}
